package pers.zb.center.service.user.api.impl.record;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pers.zb.center.common.core.service.BaseServiceImpl;
import pers.zb.center.common.core.util.DateUtil;
import pers.zb.center.common.core.vo.Pager;
import pers.zb.center.service.user.api.record.VisitRecordService;
import pers.zb.center.service.user.dao.record.VisitRecordMapper;
import pers.zb.center.service.user.entity.record.VisitRecord;
import pers.zb.center.service.user.vo.record.AccessStatisticsVo;
import pers.zb.center.service.user.vo.sys.UserVo;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("visitRecordServiceImpl")
public class VisitRecordServiceImpl extends BaseServiceImpl<VisitRecord> implements VisitRecordService {

    @Autowired
    private VisitRecordMapper visitRecordMapper;

    @Override
    public VisitRecord selectBySessionId(String sessionId) throws Exception {
        Example example = new Example(VisitRecord.class);
        example.createCriteria().andEqualTo("reqSessionId", sessionId);
        List<VisitRecord> list = visitRecordMapper.selectByExample(example);
        return (list == null || list.size() <= 0) ? null : list.get(0);
    }

    @Override
    public VisitRecord getLastLogin(String userName) throws Exception {
        return visitRecordMapper.getLastLogin(userName);
    }

    @Override
    public Integer getCurUserDayLoginNum(String userName,String day) throws Exception {
        Integer curUserTodayLoginNum = visitRecordMapper.getCurUserDayLoginNum(userName,day);
        return curUserTodayLoginNum;
    }

    @Override
    public TreeMap<String, TreeSet<AccessStatisticsVo>> accessStatistics(String dateStr, int dayNum) throws Exception {
        //需要查询的日期列表
        List<String> dateList = new ArrayList<String>();

        //这个dateStr作为最后面的日期，然后往前推算dayNum天进行统计
        if(StringUtils.isBlank(dateStr)){
            dateStr = DateUtil.getDateFormat(new Date());//默认当前系统日期，yyyy-MM-dd
        }
        if(dayNum <= 0){
            dayNum = 7;//默认查询7天
        }

        //初始化所有的天数和每天24小时的统计数据，每个小时中的系统请求数与客户端数量默认都为0。然后从数据库中获取最新数据后，进行更新map
        TreeMap<String, TreeSet<AccessStatisticsVo>> allDate = new TreeMap<String, TreeSet<AccessStatisticsVo>>();
        for (int i = 0; i < dayNum ; i++){
            //获取前一天的日期，当i为0的时候，表示当天
            String str = dateOperation(dateOperationEnum.SUB.toString(),dateStr,i);
            dateList.add(str);

            //TreeSet支持排序，故对于1到24点的数值，需要进行升序排序
            TreeSet<AccessStatisticsVo> dateHourData = new TreeSet<AccessStatisticsVo>();
            for (int j = 1; j <= 24; j++){
                AccessStatisticsVo vo =  new AccessStatisticsVo(str,j,0,0);
                dateHourData.add(vo);
            }
            allDate.put(str,dateHourData);
        }

        //数据库中获取系统访问统计结果
        List<AccessStatisticsVo> list = visitRecordMapper.accessStatistics(dateList);

        //将结果集进行处理，将treeMapDate之前初始化好的默认数据，进行替换更新
        TreeMap<String, TreeSet<AccessStatisticsVo>> data = new TreeMap<String, TreeSet<AccessStatisticsVo>>();

        for (AccessStatisticsVo vo: list) {
            String dateVal = vo.getDateVal();
            if(allDate.containsKey(dateVal)){//判断初始化好的结果集中是否存在对应日期的数据
                TreeSet<AccessStatisticsVo> dateHourData = allDate.get(dateVal);//获取对应日期中的默认初始化数据
                if(dateHourData.contains(vo)){//如果对应日期内的默认数据与数据库中的数据重复，需要先移除。替换为数据库中最新结果
                    dateHourData.remove(vo);//移除之前初始化好的默认数据，以免出现重复记录
                    dateHourData.add(vo);//将数据库中的结果加入到set集合中
                }
            }
        }
        return allDate;
    }

    @Override
    public Pager<VisitRecord> getList(Pager<VisitRecord> pager, VisitRecord visitRecord) throws Exception {
        if (pager.getUsePager()) {
            PageHelper.offsetPage(pager.getOffset(), pager.getLimit());
        }

        Condition condition = new Condition(VisitRecord.class);
        condition.setOrderByClause("create_time desc");

        List<VisitRecord> vos = visitRecordMapper.selectByExampleAndRowBounds(condition,new RowBounds(pager.getOffset(),pager.getLimit()));
        pager.setRows(vos);
        PageInfo<VisitRecord> pageInfo = new PageInfo<VisitRecord>(vos);
        pager.setTotal(pageInfo.getTotal());
        return pager;
    }

    /**
     * 日期加减一天
     * @param option
     * @param dateStr
     * @param dayNum
     * @return
     * @throws Exception
     */
    public static String dateOperation(String option, String dateStr,int dayNum) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cl = Calendar.getInstance();
        Date date = null;

        try {
            date = (Date) sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new Exception("日期转换出现错误");
        }
        cl.setTime(date);
        if (dateOperationEnum.SUB.toString().equals(option)) {
            // 时间减一天
            cl.add(Calendar.DAY_OF_MONTH, -dayNum);

        } else if (dateOperationEnum.ADD.toString().equals(option)) {
            // 时间加一天
            cl.add(Calendar.DAY_OF_YEAR, dayNum);
        }else{
            throw new Exception("日期操作出现错误");
        }
        date = cl.getTime();
        return sdf.format(date);
    }
    enum dateOperationEnum{
        ADD,SUB
    }

}
